<script lang="ts" setup>
import type { SelectValue } from 'ant-design-vue/es/select';

import type { LanguageSupport } from '@vben/common-ui';

import { reactive, ref, watchEffect } from 'vue';

import { CodeMirror } from '@vben/common-ui';
import { storeToRefs } from '@vben/stores';

import { Form, FormItem, message, Select, Space } from 'ant-design-vue';
import dayjs from 'dayjs';

import { deviceTopic } from '#/api/iot/device/manage';
import { useMqttStore } from '#/store/mqtt';

import mqttService from '../../mqtt';

const useMqtt = useMqttStore();
const { mqttOption } = storeToRefs(useMqtt);

const topic = ref('');

const infoState = reactive<{
  attribute: string | undefined;
  json: string;
}>({
  attribute: undefined,
  json: `\n\n\n\n\n\n\n\n\n`,
});
const topicOptions = ref<{ blockName: string; id: string }[]>([]); // 服务数据
const language = ref<LanguageSupport>('json');

watchEffect(async () => {
  if (mqttOption.value.deviceId) {
    await getThingModelSelect(mqttOption.value.deviceId as string);
  }
});

async function getThingModelSelect(deviceId: string) {
  const { rows }: any = await deviceTopic({
    pageNum: 1,
    pageSize: 999,
    topicSourceType: 2,
    topicDirection: 1,
    deviceId,
  });

  topicOptions.value = rows;
}

const handleTopic = (value: SelectValue) => {
  topic.value = value as string;
  subscribe(value as string);
};
// 订阅MQTT
const subscribe = (topic: string) => {
  mqttService.subscribe(topic); // Subscribe to the topic
  useMqtt.setMqttTable({
    time: dayjs().format('YYYY-MM-DD HH:mm:ss'),
    type: '订阅主题',
    content: `Topic:${topic}`,
  });
};
// MQTT传值
function publish(topic: string, value: string) {
  mqttService.publish(topic, value); // Publish a message to the topic
  useMqtt.setMqttTable({
    time: dayjs().format('YYYY-MM-DD HH:mm:ss'),
    type: '设备上行',
    content: `Content:${value}`,
  });
}

function onSubmit() {
  if (!infoState.attribute) return message.warning(`请选择自定义Topic`);
  if (!infoState.json) return message.warning(`请输入指令`);
  if (!isValidJSON(infoState.json)) return message.warning(`JSON格式不正确`);
  publish(topic.value, JSON.stringify(infoState.json.trim()));
}
// 格式化json
const formatCode = () => {
  if (!isValidJSON(infoState.json)) return message.warning(`JSON格式不正确`);
  // 先将 JSON 字符串解析为 JavaScript 对象
  const jsonObj = JSON.parse(infoState.json);
  // 使用 JSON.stringify 进行美化
  infoState.json = JSON.stringify(jsonObj, null, 2);
};

function isValidJSON(jsonString: string) {
  try {
    JSON.parse(jsonString);
    return true;
  } catch {
    // 如果解析过程中抛出错误，则说明不是合法的 JSON 格式
    return false;
  }
}
function onReset() {
  infoState.json = `\n\n\n\n\n\n\n\n\n`;
}
</script>
<template>
  <div>
    <Form :model="infoState" layout="vertical">
      <FormItem>
        <Select
          v-model:value="infoState.attribute"
          placeholder="请选择自定义Topic"
          :options="topicOptions"
          :field-names="{ label: 'topic', value: 'topic' }"
          @change="handleTopic"
        />
      </FormItem>
      <FormItem>
        <CodeMirror v-model="infoState.json" :language="language" basic />
      </FormItem>
      <FormItem :wrapper-col="{ offset: 0 }">
        <Space>
          <a-button type="primary" @click="onSubmit">发送指令</a-button>
          <a-button @click="formatCode">格式化数据</a-button>
          <a-button @click="onReset">重置数据</a-button>
        </Space>
      </FormItem>
    </Form>
  </div>
</template>
<style scoped lang="scss"></style>
